#include <new>
#include <unistd.h>
#include <sys/socket.h>
#include "WorkSvr.h"
#include "SvrMgr.h"

#define SERVER_PORT 9898

bool ServerPtr::NewServer()
{
    pSvr = new CWorkSvr();
    return (nullptr != pSvr);
}

void ServerPtr::DestroyServer()
{
    if (nullptr != pSvr)
    {
        delete pSvr;
        pSvr = nullptr;
    }
}

CSvrMgr::CSvrMgr()
{
    m_ilfd = -1;
}

CSvrMgr::~CSvrMgr()
{
    Destroy();
}

void *CSvrMgr::operator new(size_t sz)
{
    CMemPool *mp = CMemPool::GetInstance();

    if (nullptr == mp)
        return NULL;

    return mp->Alloc(sz);
}

void CSvrMgr::operator delete(void *ptr)
{
    CMemPool *mp = CMemPool::GetInstance();

    if (nullptr != mp)
        mp->Free(ptr);
}

int CSvrMgr::CreateListenSocket()
{
    if (-1 != m_ilfd)
        return m_ilfd;

    int fd = CServer::BindAndListen(SERVER_PORT);

    if (0 >= fd)
        return -1;

    m_ilfd = fd;
    return fd;
}

void CSvrMgr::CloseListenSocket()
{
    if (-1 != m_ilfd)
    {
        close(m_ilfd);
        m_ilfd = -1;
    }
}

ServerNode *CSvrMgr::CreateServerNode()
{
    bool bRet = false;
    ServerNode *pNode = m_lstSvr.NewNode();

    if (nullptr == pNode)
        return nullptr;

    if (!pNode->NewServer())
    {
        m_lstSvr.DeleteNode(pNode);
        return nullptr;
    }

    bRet = m_lstSvr.PushBack(pNode);

    if (!bRet)
    {
        m_lstSvr.DeleteNode(pNode);
        return nullptr;
    }

    return pNode;
}

void CSvrMgr::DestroyServerNode(ServerNode *pNode)
{
    if (nullptr == pNode)
        return;

    m_lstSvr.Remove(pNode);
    m_lstSvr.DeleteNode(pNode);
}

void CSvrMgr::Destroy()
{
    CServer *pSvr = nullptr;
    ServerNode *pNode = nullptr;

    CloseListenSocket();
    pNode = m_lstSvr.GetHeader();

    while (nullptr != pNode)
    {
        pSvr = pNode->pSvr;

        if (nullptr != pSvr)
        {
            pSvr->Destroy();
            delete pSvr;
            pNode->pSvr = nullptr;
        }

        pNode = pNode->Next();
    }

    m_lstSvr.Destroy();
}

// 待优化
CServer *CSvrMgr::GetAcceptServer()
{
    CServer *pMinSvr = nullptr;
    CServer *pTmpSvr = nullptr;
    ServerNode *pNode = m_lstSvr.GetHeader();

    while (nullptr != pNode)
    {
        pTmpSvr = pNode->pSvr;

        if (nullptr == pTmpSvr)
            return nullptr;

        if (nullptr == pMinSvr)
        {
            pMinSvr = pTmpSvr;
        }
        else if (pMinSvr->GetClientCount() > pTmpSvr->GetClientCount())
        {
            pMinSvr = pTmpSvr;
        }

        pNode = pNode->Next();
    }

    return pMinSvr;
}

void CSvrMgr::StopServer()
{
    CServer *pSvr = nullptr;
    ServerNode *pNode = nullptr;

    pNode = m_lstSvr.GetHeader();

    while (nullptr != pNode)
    {
        pSvr = pNode->pSvr;

        if (nullptr != pSvr)
            pSvr->Stop();

        pNode = pNode->Next();
    }
}